﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ServiceKit.Aop;
using ServiceKit.JsonRpc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace ServiceKit.WebApi
{
    //https://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/
    //https://damienbod.com/2015/09/15/asp-net-5-action-filters/
    //[ServiceFilter(typeof(ActionAuditFilterAttribute))]
    public class DynamicApiController<T> : Controller where T : IService
    {
        private IOptions<RpcServerConfiguration> serverConfig { get; }
        private IRpcInvoker invoker { get; }

        public DynamicApiController(IOptions<RpcServerConfiguration> serverConfig,
            IRpcInvoker invoker)
        {
            this.serverConfig = serverConfig ?? throw new ArgumentNullException(nameof(serverConfig));
            this.invoker = invoker ?? throw new ArgumentNullException(nameof(invoker));
        }

        [HttpGet]
        public string get()
        {
            return "ok";
        }

        [HttpPost]
        [ActionAuditFilter]
        public RpcResponse post()
        {
            var auditData = AuditFilterData.GetOrNull(this);
            string jsonstring = getJsonString(this.HttpContext.Request);
            RpcRequest request = JsonConvert.DeserializeObject<RpcRequest>(jsonstring);
            if (auditData == null)
            {

                var ex = new RpcException(500, "非法请求！");
                RpcError error = new RpcError(ex, true);
                var rpcResponse = new RpcResponse(request.Id, error);
                return rpcResponse;

            }
            else
            {
                auditData.AuditInfo.ServiceName = request.Method;
                auditData.AuditInfo.Parameters = request.Parameters.ToString();
                T service = (T)this.HttpContext.RequestServices.GetService(typeof(T));
                var response = invoker.InvokeRequestAsync<T>(request, service);
                return response.Result;
            }

        }

        private static string getJsonString(HttpRequest request)
        {
            string documentContents;
            using (Stream receiveStream = request.Body)
            {
                using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
                {
                    documentContents = readStream.ReadToEnd();
                }
            }
            return documentContents;
        }
    }
}
